﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using PhysicsProject.Infrastructure.Concrete;
using PhysicsProject.Models;

namespace PhysicsProject.ViewModels
{
    public class EnvironmentViewModel : ViewModelBase
    {
        private static readonly PhysicsEnvironment PhysicsEnvironmentModel;

        private ObservableCollection<ThermometerViewModel> _thermometers;

        public DelegateCommand StartExecution { get; set; }
        public DelegateCommand StopExecution { get; set; }
        public DelegateCommand AddBoxExecution { get; set; }

        public ObservableCollection<BoxViewModel> Boxes { get; set; }
        public ObservableCollection<ThermometerViewModel> Thermometers
        {
            get { return new ObservableCollection<ThermometerViewModel>(_thermometers.Where(c => c != _thermometers.Last())); }
            set
            {
                _thermometers = value; 
                OnPropertyChanged();
            }
        }

        public ThermometerViewModel LastThermometer
        {
            get { return _thermometers.Last(); }
        }

        public IEnumerable<Material> Materials
        {
            get { return Material.Materials; }
        }

        static EnvironmentViewModel()
        {
            PhysicsEnvironmentModel = new PhysicsEnvironment();
        }

        public EnvironmentViewModel()
        {
            AddBoxExecution = new DelegateCommand(AddBox);
            Boxes = new ObservableCollection<BoxViewModel>();
            _thermometers = new ObservableCollection<ThermometerViewModel>();

            var initialBox = new Box();
            _thermometers.Add(new ThermometerViewModel(new Thermometer(null, initialBox), true));
            _thermometers.Add(new ThermometerViewModel(new Thermometer(initialBox), true));
            Boxes.Add(new BoxViewModel(initialBox));
        }

        public void step(uint numSeconds)
        {
            for (int j = 0; j < Boxes.Count - 1; j++)
            {
                ThermometerViewModel meterLeft = Thermometers.ElementAt(j);
                ThermometerViewModel meterRight = Thermometers.ElementAt(j + 1);

                ThermometerViewModel hotter = meterLeft.CurrentTemperature > meterRight.CurrentTemperature
                                                  ? meterLeft
                                                  : meterRight;

                ThermometerViewModel colder = meterLeft.CurrentTemperature > meterRight.CurrentTemperature
                                                  ? meterRight
                                                  : meterLeft;

                BoxViewModel box = Boxes.ElementAt(j);
                float k = box.MaterialType.Coefficient;
                float deltaT = hotter.CurrentTemperature - colder.CurrentTemperature;

                float Q = k * deltaT * numSeconds;
                hotter.CurrentTemperature -= Q;
                colder.CurrentTemperature += Q;
            }
        }

        public void AddBox()
        {
            var box = new Box();
            var lastThermometer = _thermometers.Last();
            _thermometers.Remove(lastThermometer);
            var existingLeftBox = lastThermometer.LeftBox;
            lastThermometer.LeftBox = box;
            _thermometers.Add(new ThermometerViewModel(new Thermometer(existingLeftBox, box)));
            _thermometers.Add(lastThermometer);
            Boxes.Add(new BoxViewModel(box));
            OnPropertyChanged("Thermometers");
            OnPropertyChanged("LastThermometer");
        }
    }
}